package com.star.uc.biz;

import cn.dev33.satoken.stp.StpUtil;
import com.star.config.api.contract.query.UserTenantConfigQuery;
import com.star.config.api.contract.vo.UserTenantConfigVO;
import com.star.config.api.service.ConfigApi;
import com.star.uc.contract.command.LogoffCommand;
import com.star.uc.contract.dto.request.LoginRequest;
import com.star.uc.contract.dto.response.LoginResponse;
import com.star.config.api.contract.enums.LoginExclusionTypeEnum;
import com.star.uc.contract.param.UserInfoParam;
import com.star.uc.contract.param.UserOuterMapperInfoParam;
import com.star.uc.factory.login.LoginTypeFactory;
import com.star.uc.factory.login.LoginTypeOperator;
import com.star.uc.infras.repository.model.UserInfoBO;
import com.star.uc.infras.repository.model.UserOuterMapperInfoBO;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

/**
 * 用户增删改业务处理类
 *
 * @author zhouhengzhe
 */
@Service
@RequiredArgsConstructor
public class UserBizService {

    private final LoginTypeFactory loginTypeFactory;

    private final ConfigApi configApi;

    /**
     * 登录验证
     *
     * @param loginRequest 登录方式
     * @return 结果
     */
    public LoginResponse login(LoginRequest loginRequest) {
        LoginTypeOperator loginTypeOperator = loginTypeFactory.route(loginRequest.getLoginType());
        //获取用户信息
        UserInfoBO userInfoBO = loginTypeOperator.authorize(loginRequest);
        //登录，如果需要往jwt的token中添加数据，可以用
//        StpUtil.login(userInfo.getUid(), SaLoginConfig
//                .setExtra("name", "zhangsan")
//                .setExtra("age", 18)
//                .setExtra("role", "超级管理员"));
        //获取用户配置信息
        UserTenantConfigVO userTenantConfigVO = configApi.getUserTenantConfig(UserTenantConfigQuery.builder().tenantId(userInfoBO.getTenantId()).build());
        if (LoginExclusionTypeEnum.EXCLUSION.getCode().equals(userTenantConfigVO.getLoginExclusionType())) {
            //踢账号其他登录下线
            StpUtil.kickout(userInfoBO.getUid());
        }
        //登录绑定设备
        StpUtil.login(userInfoBO.getUid(), loginRequest.getClientType());
        //获取token
        String tokenValue = StpUtil.getTokenValue();
        // todo 保存登录日志(量大建议走RocketMQ/kafka)，默认走本地监听，然后保存到日志表中，正常来说为了解耦合应该用spring的监听，或者用RocketMQ/kafka，第一版不实现


        //todo 发送登录事件（发送到rocketMQ/kafka中）,第一版不实现，看后面需求

        //返回结果
        return LoginResponse.builder()
                .token(tokenValue)
                .loginType(loginRequest.getLoginType())
                .uid(userInfoBO.getUid())
                .build();
    }

    /**
     * 注销
     *
     * @param logoffCommand 注销参数
     */
    public void logoff(LogoffCommand logoffCommand) {
        //删除用户信息
        UserInfoBO.repository().delete(UserInfoParam.builder().uid(logoffCommand.getUid()).build());
        //删除对应的三方信息,有可能多个
        UserOuterMapperInfoBO.repository().delete(UserOuterMapperInfoParam.builder().uid(logoffCommand.getUid()).build());
        //登出所有相关的信息Token
        StpUtil.logout(logoffCommand.getUid());
        //todo 发送登出事件（发送到rocketMQ/kafka中）,目前只考虑基础版本的，不考虑高级版本的


    }

}
